package cc.decat.escript.object;

import java.util.HashMap;
import java.util.Map;

public class ESDictObject extends ESObject {

    private Map<ESObject, ESObject> map = new HashMap<>();

    public ESDictObject() {
        super(ESDictType.getInstance());
    }

    public Map<ESObject, ESObject> getMap() {
        return map;
    }
}


class ESDictType extends ESType {

    private static final ESDictType instance = new ESDictType();

    public static ESDictType getInstance() {
        return instance;
    }

    public ESDictType() {
        super("Dict");
    }


    @Override
    public ESObject len(ESObject x) {
        return ESIntegerObject.fromValue((long) ((ESDictObject)x).getMap().size());
    }

    @Override
    public ESObject str(ESObject x) {
        ESDictObject dictObj = (ESDictObject) x;
        Map<ESObject, ESObject> map = dictObj.getMap();
        if(map.size() == 0) {
            return ESStringObject.fromValue("{}");
        } else if(map.size() == 1) {
            for(ESObject key : map.keySet()) {
                ESObject val = map.get(key);
                String s = "{ " + ((ESStringObject) key.getType().str(key)).getStr();
                s += " : ";
                s += ((ESStringObject) val.getType().str(val)).getStr();
                s += " }";
                return ESStringObject.fromValue(s);
            }
        } else {
            int i = 0;
            StringBuilder sb = new StringBuilder();
            sb.append("{");
            for(ESObject key : map.keySet()) {
                i++;
                ESObject val = map.get(key);
                sb.append(" ");
                sb.append(((ESStringObject) key.getType().str(key)).getStr());
                sb.append(" : ");
                sb.append(((ESStringObject) val.getType().str(val)).getStr());
                if(i < map.size()) {
                    sb.append(",");
                }
            }
            sb.append(" }");
            return ESStringObject.fromValue(sb.toString());
        }
        return super.str(x);
    }

    @Override
    public ESObject getSubscr(ESObject lhs, ESObject rhs) {
        return ((ESDictObject) lhs).getMap().getOrDefault(rhs, ESConstObjects.NULL);
    }

    @Override
    public void setSubscr(ESObject lhs, ESObject mhs, ESObject rhs) {
        ((ESDictObject) lhs).getMap().put(mhs, rhs);
    }
}